#include "BoundingBox.h"

BoundingBox::BoundingBox(void)
{
	minimum = new Point3(POSITIVE_INFINITY, POSITIVE_INFINITY, POSITIVE_INFINITY);
	maximum = new Point3(NEGATIVE_INFINITY, NEGATIVE_INFINITY, NEGATIVE_INFINITY);
	center = new Point3();
	extents = new Vector3();
}

BoundingBox::~BoundingBox(void)
{
}

Point3* BoundingBox::getMinimum()
{
	return minimum;
}

Point3* BoundingBox::getMaximum()
{
	return maximum;
}

Point3* BoundingBox::getCenter()
{
	return Point3::mid(*minimum, *maximum, center);
}

Vector3* BoundingBox::getExtents()
{
	return Point3::sub(*maximum, *minimum, extents);
}

void BoundingBox::scale( double s )
{
	Point3::mid(*minimum, *maximum, center);
	Point3::sub(*maximum, *minimum, extents);
	s *= (s > 0.0) ? 0.5 : -0.5;
	minimum->x = center->x - extents->x * s;
	minimum->y = center->y - extents->y * s;
	minimum->z = center->z - extents->z * s;
	maximum->x = center->x + extents->x * s;
	maximum->y = center->y + extents->y * s;
	maximum->z = center->z + extents->z * s;
}

bool BoundingBox::isEmpty()
{
	return maximum->x < minimum->x || maximum->y < minimum->y || maximum->z < minimum->z;
}

bool BoundingBox::intersects( BoundingBox* b )
{
	return (b != 0 &&
		minimum->x <= b->maximum->x && maximum->x >= b->minimum->x &&
		minimum->y <= b->maximum->y && maximum->y >= b->minimum->y &&
		minimum->z <= b->maximum->z && maximum->z >= b->minimum->z);
}

bool BoundingBox::contains( Point3* p )
{
	return (p != 0 &&
		p->x >= minimum->x && p->x <= maximum->x &&
		p->y >= minimum->y && p->y <= maximum->y &&
		p->z >= minimum->z && p->z <= maximum->z);
}

void BoundingBox::include( Point3* p )
{
	if (p != 0) {
		if (p->x < minimum->x) minimum->x = p->x;
		if (p->x > maximum->x) maximum->x = p->x;
		if (p->y < minimum->y) minimum->y = p->y;
		if (p->y > maximum->y) maximum->y = p->y;
		if (p->z < minimum->z) minimum->z = p->z;
		if (p->z > maximum->z) maximum->z = p->z;
	}
}

void BoundingBox::include( BoundingBox* b )
{
	if (b != 0) {
		if (b->minimum->x < minimum->x) minimum->x = b->minimum->x;
		if (b->maximum->x > maximum->x) maximum->x = b->maximum->x;
		if (b->minimum->y < minimum->y) minimum->y = b->minimum->y;
		if (b->maximum->y > maximum->y) maximum->y = b->maximum->y;
		if (b->minimum->z < minimum->z) minimum->z = b->minimum->z;
		if (b->maximum->z > maximum->z) maximum->z = b->maximum->z;
	}
}